package funcionamento;

/** 
 * @author Gean
 * 121151418
 * @author Eduardo
 * 121151427
 */
public class Fila {

    protected Processo[] data;
    protected int inicio;
    protected int fim;
    protected int qtdPosLivre;

    public Fila(int tamanho) {                       // método construtor da fila, que recebe como parametro o tamanha que essa fila terá
        data = new Processo[tamanho];
        inicio = 0;
        fim = 0;
        qtdPosLivre = tamanho;
    }
    
    public void enqueue(Processo processo) {            // método que coloca elementos na fila e tem como parametro um elemento do tipo "processo"
        if (getQtdPosLivre() == 0) {                 
            System.out.println("Fila Cheia!!!!");
            
       }else if (getFim() == getData().length-1){
           getData()[getFim()] = processo;
           setFim(0);
           setQtdPosLivre(getQtdPosLivre() - 1);                             
          
       }else{
              getData()[getFim()] = processo;
              processo.setTempoDeChegada(getFim());
              setFim(getFim()+1);
              setQtdPosLivre(getQtdPosLivre() - 1);
            }      
    }

    public void dequeue() {                                         // método que retira elementos da fila
        if (getQtdPosLivre() == getData().length) {                 
            System.out.println("Fila vazia!");
        
        } else if(getInicio() == getData().length-1){    
            getData()[getInicio()] = null;
            setInicio(0);
            setQtdPosLivre(getQtdPosLivre() + 1);
            
        } else {
            getData()[getInicio()] = null;
            setInicio(getInicio() + 1);
            setQtdPosLivre(getQtdPosLivre() + 1);
         
        }
      }
    
     public Processo dequeue(int posicao) {                                         // dequeue sobreescrito para que seja possivel retirar um elemento especifico da fila, ou seja, é passado como parametro a pocisao da fila que se quer retirar
       Processo retorno;                                                               // variavel auxiliar usada para armazenar o elemento a ser excluido da fila
       retorno = getData()[posicao];
       getData()[posicao] = null;
       setQtdPosLivre(getQtdPosLivre() + 1);
     
     return retorno;                                                                    // retorna o elemento retirado...
      }
    
    /* Métodos gets e sets para que seja possivel
     * acessar os atributos privados abaixo em
     * outras classes
     */
    public Processo[] getData() {
        return data;
    }

    public void setData(Processo[] data) {
        this.data = data;
    }

    public int getInicio() {
        return inicio;
    }

    public void setInicio(int inicio) {
        this.inicio = inicio;
    }

    public int getFim() {
        return fim;
    }

    public void setFim(int fim) {
        this.fim = fim;
    }

    public int getQtdPosLivre() {
        return qtdPosLivre;
    }

    public void setQtdPosLivre(int qtdPosLivre) {
        this.qtdPosLivre = qtdPosLivre;
    }
}
